# mysql ocr 的数据与as400的数据对比
import threading
import time
from db import OCRsql
import gevent
from gevent import pool
from gevent import monkey

monkey.patch_all()


class as400_OCR(object):
    def __init__(self, minbarList, max_ticketDict, ocr_read_box_sum, start_time, end_time, sinOUT=None, serial_number=None):
        self.sinOUT = sinOUT     # 输出信号
        self.start_time = start_time          # 开始扫描时间
        self.end_time = end_time            # 结束扫描时间
        self.ocr_read_box_sum = ocr_read_box_sum    # 点数据点到实物胶箱的数量
        self.max_ticketDict = max_ticketDict  # 高拍仪数据
        self.minbarList = minbarList
        self.ocr_log_list = []  # 扫描记录
        self.outTicket_log_list = []  # 出张出库票数据记录

        self.max_ticket_list = None     # 高拍仪获取到的出张出库票数据
        self.min_HRMC_list = None       # 高拍仪小票列表
        self.Hmax_plant_dict = None     # 高拍仪关联工厂高
        self.Hmin_plant_dict = None

        self.RMC_barList = None         # 扫描RMC条码
        self.scan_RMC_count = None      # 扫描条码总数
        self.Loop_sum = 0               # 循环控制
        self.OCR_DATA = None            # OCR所有数据   s
        self.all_OCR_RMC = None         # 扫描RMC集合

        self.BOX_result = {}        # 结果报存字典  总数
        self.BOX_result2 = {}       # 结果报存字典  单数据比较
        self.RMC_result = {}        # RMC结果集
        self.REQ_result = {}        # REQ数据结果
        self.plant_result = {}      # 共厂号 检查结果

        self.serial_number = serial_number          # 生成一个序列编号  做为唯码一
        # 数据库对象
        self.ocr_db_obj = OCRsql.OCR_DB(user='ly', password='123', database='ocr', host='10.10.1.1')

    def __del__(self):
        pass

    def out_GUI(self, info):
        self.sinOUT.emit("result&%s" % str(info))

    # 筛选分类统计扫描重复条码
    def get_Scan_RMC_bar(self, RMC_bar_List):
        value_cnt = {}  # 将结果用一个字典存储
        # 统计结果
        for value in RMC_bar_List:
            # get(value, num)函数的作用是获取字典中value对应的键值, num=0指示初始值大小。
            value_cnt[value] = value_cnt.get(value, 0) + 1
        # 打印输出结果
        all_OCR_RMC = value_cnt                              # 全部结果, dict
        RMC_barList = [key for key in value_cnt.keys()]        # 去重后的条码
        count_list = [value for value in value_cnt.values()]   # 获取统计结果, 结果用List存放
        scan_RMC_count = sum(count_list)  # 条码总数

        return RMC_barList, scan_RMC_count, all_OCR_RMC    # 返回去从条码列表和统计条码总数


    # 判断两列表是否一样  返回一样 True , 否则返回False
    def if_list_equally(self, List1, List2):
        equally = False
        for minbar in List1:
            if minbar in List2:
                equally = True
            else:
                equally = False
                break
        return equally     # 返回两列表数据处理结果

    # 获取大票(出货票)在as400里的关联注册小票的所有元素
    def get_as400min_data(self, max_ticket):
        # as400Data = self.as400_sync_db_obj.max_get_as400_data(max_ticket)  # 访问AS400出货指令数据, 返回字典
        # 返回是列表套字典
        as400Data = self.ocr_db_obj.item_getdata(item="ticket_bar", item_value=max_ticket, db_name="as400_sync")
        ASmax_plant_dict = {}  # AS获取到大票的工厂代码
        ASmin_plant_dict = {}  # AS获取到小票的工厂代码
        ASmin_RMC_list = []
        for data_dict in as400Data:   #[{'id': 1, 'RMC_bar': 'D2421231-+-P', 'ticket_bar': 3242136, 'plant': 3140,}]
            ASmin_RMC_list.append(data_dict["RMC_bar"])
            ticket_bar = data_dict["ticket_bar"]
            plant = int(data_dict["plant"])
            if ASmax_plant_dict.__contains__(ticket_bar) == False:      # 不添加重复数据
                ASmax_plant_dict[ticket_bar] = {"plant": plant}
            ASmin_plant_dict[data_dict["RMC_bar"]] = {"plant": plant}
        return as400Data, ASmax_plant_dict, ASmin_plant_dict, ASmin_RMC_list

    # 在扫描获取到的条码异常情况下,,提取条码不一样的数据
    def get_scan_mare_RMC(self, muchList, littleList):    #  (参数1, 参数2)   # 参数多的放在前面, 参数小的放在后面
        b = None
        if len(muchList) > len(littleList):
            pass
        else:
            if len(muchList) < len(littleList):
                b = muchList
                muchList = littleList
                littleList = b
        alike_bar = []   # 条码相同部分
        much_bar = []    # 条码不重叠部分
        for k, minbar in enumerate(muchList):    # 参数大的线循环
            if_no = True
            for RMC in littleList:
                if RMC == minbar:
                    alike_bar.append(minbar)  # 扫描数据与AS400数据相同部分
                    if_no = False
            if if_no:
                much_bar.append(minbar)  # 扫描数据多于AS400备案数据

        for k, minbar in enumerate(littleList):    # 参数大的线循环
            if_no = True
            for RMC in muchList:
                if RMC == minbar:
                    if not RMC in alike_bar:
                        alike_bar.append(minbar)  # 扫描数据与AS400数据相同部分
                    if_no = False
            if if_no:
                much_bar.append(minbar)  # 扫描数据多于AS400备案数据
        return alike_bar, much_bar

    # 高怕仪获取信息分类
    def get_RMC_info(self, max_ticket):
        max = []    # 高拍仪出张出库票
        min = []    # 高拍仪读取的RMC部番条码
        Hmax_plant_dict = {}  # 高拍仪获取到大票的工厂代码
        Hmin_plant_dict = {}  # 高拍仪获取到小票的工厂代码
        for max_bar in max_ticket:
            max.append(max_bar)
            for RMC in max_ticket[max_bar]:
                min.append(RMC)
                Hmax_plant_dict[max_bar] = {"plant": max_ticket[max_bar][RMC]["plant"]}
                Hmin_plant_dict[RMC] = {"plant": max_ticket[max_bar][RMC]["plant"]}
        return max, min, Hmax_plant_dict, Hmin_plant_dict   # 返回大票, 小票, 对应工厂号

    # 工厂代码  检查
    def check_plant(self, OCR_CATA):
        # 出张出库票对应的工厂号集合
        H_max_plant = OCR_CATA["Hmax_plant_dict"]
        # 出货指令出张出库票对应工厂号数据集合
        AS_max_plant = OCR_CATA["ASmax_plant_dict"]
        # 如果两数据相等直接过
        if not H_max_plant == AS_max_plant:
            for Hmax_bar in H_max_plant:
                for ASmax_bar in AS_max_plant:
                    if Hmax_bar == ASmax_bar:
                        if H_max_plant[Hmax_bar]['plant'] != AS_max_plant[ASmax_bar]['plant']:
                            self.plant_result[Hmax_bar] = {'plant': 0}  # 不相等  赋值 0 记录异常数据

    # 生成胶箱与条码读取数量, 种类比较结果代码
    def BOX_CODE(self, BOX_result):
        # 读取条码与点胶箱数不尽  1 是OCR大于,  8 是小于, 0 是等于
        if BOX_result["RbarLen_RboxLen"] > 0:
            Rbar = 1
        elif BOX_result["RbarLen_RboxLen"] < 0:
            Rbar = 8
        else:
            Rbar = 0
        # 点的胶箱与关联AS400胶箱
        if BOX_result["RboxLen_as400BOX"] > 0:
            Rbox = 1
        elif BOX_result["RboxLen_as400BOX"] < 0:
            Rbox = 8
        else:
            Rbox = 0
        # OCR条码与高拍仪识别条码数量
        if BOX_result["RbarLen_HrbarRMC"] > 0:
            RHbar = 1
        elif BOX_result["RbarLen_HrbarRMC"] < 0:
            RHbar = 8
        else:
            RHbar = 0
        # OCR条码种类与高拍仪条码种类
        if BOX_result["RbarLen_AS400barLen"] > 0:
            RAbar = 1
        elif BOX_result["RbarLen_AS400barLen"] < 0:
            RAbar = 8
        else:
            RAbar = 0
        # 高拍仪胶箱与AS400胶箱
        if BOX_result["HBOX_AS400BOX"] > 0:
            HAbox = 1
        elif BOX_result["HBOX_AS400BOX"] < 0:
            HAbox = 8
        else:
            HAbox = 0
        # OCR条码数量与AS400条码数量
        if BOX_result["OCRbar_as400barlen"] > 0:
            OAbar = 1
        elif BOX_result["OCRbar_as400barlen"] < 0:
            OAbar = 8
        else:
            OAbar = 0
        # OCR条码数量与搞怕仪条码数量
        if BOX_result["OCRbar_Hbar"] > 0:
            OHbar = 1
        elif BOX_result["OCRbar_Hbar"] < 0:
            OHbar = 8
        else:
            OHbar = 0

        BOX_code = str(Rbar) + str(Rbox) + str(RHbar) + str(RAbar) + str(HAbox) + str(OAbar) + str(OHbar)
        return BOX_code

    # 胶箱数比较
    def check_BOX(self, OCR_DATA):
        as400_BOX_count = 0    # AS400胶箱
        read_BOX_count = 0    # 高拍仪胶箱
        OCR_RMC_list = OCR_DATA["minbarList"]          # 没有去重的条码列表
        Has400Data = OCR_DATA["HgetAS400Data"]          # 出货指令数据  列表套字典
        max_ticketDict = OCR_DATA["max_ticketDict"]     # 高拍仪读取的数据
        ocr_read_box_sum = OCR_DATA["ocr_read_box_sum"]  # 实物胶箱数
        RMC_barList = OCR_DATA["RMC_barList"]                # OCR扫描条码
        min_HRMC_list = OCR_DATA["min_HRMC_list"]           # 高怕仪读取的条码
        H_BOX = {}    # 高派件记录箱数
        AS_BOX = {}   # 出货指令记录箱数
        # 出货指令胶箱
        for minbar in Has400Data:
            as400_BOX_count += int(minbar["BOX"])    # 出货指令 胶箱总数
            AS_BOX[minbar['RMC_bar']] = int(minbar["BOX"])      # 出货指令对应部番的胶箱数
        # 出张出库票胶箱
        for maxbar in max_ticketDict:
            for RMC_bar in max_ticketDict[maxbar]:
                read_BOX_count += int(max_ticketDict[maxbar][RMC_bar]["BOX"])           # 高拍仪读取胶箱
                H_BOX[RMC_bar] = int(max_ticketDict[maxbar][RMC_bar]["BOX"])

        self.BOX_result["RbarLen_RboxLen"] = OCR_DATA["scan_RMC_count"] - ocr_read_box_sum      # 扫码数量 与 实物胶箱  正数为扫描多,  负数为实物多 0 为相等
        self.BOX_result["RboxLen_as400BOX"] = ocr_read_box_sum - as400_BOX_count                # 实物胶箱 与 出货指令胶箱
        self.BOX_result["RbarLen_HrbarRMC"] = len(RMC_barList) - len(min_HRMC_list)             # 扫码与高拍仪条码种类,正数为OCR多读,负数为OCR多读
        self.BOX_result["RbarLen_AS400barLen"] = len(RMC_barList) - len(Has400Data)             # 扫码条码与AS400条码种类 正数为多来, 负数为少来
        self.BOX_result["HBOX_AS400BOX"] = read_BOX_count - as400_BOX_count                     # 高拍仪胶箱 与 出货指令胶箱 正数为多来,负数为少来
        self.BOX_result["OCRbar_as400barlen"] = len(OCR_RMC_list) - as400_BOX_count             # 扫码条码与出货指令条码数量 正数为多来, 负数为少来
        self.BOX_result["OCRbar_Hbar"] = len(OCR_RMC_list) - read_BOX_count                     # 扫码条码数量与高拍仪条码数量 正数为多来, 负数为少来

        # 获取结果代码
        code = self.BOX_CODE(self.BOX_result)
        # 一箱一条码
        # 读取条码与实物, 实物与关系AS胶箱, 读条码种类与高拍仪条码种类, 读条码种类与AS400条码种类, 高拍仪读胶箱与关联AS400胶箱, 读条码数量与关联条码数量 , 读条码数量与高拍仪条码数量
        # 0: 相等, 1: 大于, 8: 小于
        self.BOX_result["code"] = code
        # OCR&S, S&AS, OCR2&h2,
        self.out_GUI("胶箱里的代码:%s (0: 相等, 1: 大于, 8: 小于)" % str(self.BOX_result["code"]))

        if self.BOX_result["RbarLen_RboxLen"] < 0:  # 条码与胶箱数不符合触发自动扫描或人工处理
            self.Rbar_Rbox(OCR_DATA)
            self.out_GUI("OCR读取条码少于实物箱数, 漏读/或少读, 触发自动扫描或现场人员处理")
            pass

        # 读取的条码与搞怕仪读取条码数量比较
        if self.BOX_result["RbarLen_RboxLen"] > 0 and self.BOX_result["OCRbar_Hbar"] > 0:
            for RMC_bar in OCR_DATA["all_OCR_RMC"]:
                try:
                    if OCR_DATA["all_OCR_RMC"][RMC_bar] != H_BOX[RMC_bar]:
                        self.BOX_result2[RMC_bar] = {"Rbar": int(OCR_DATA["all_OCR_RMC"][RMC_bar]),
                                                     "Hbar": int(H_BOX[RMC_bar]),
                                                     "num": int(OCR_DATA["all_OCR_RMC"][RMC_bar]) - int(H_BOX[RMC_bar])}
                except KeyError:
                    self.BOX_result2[RMC_bar] = {"Rbar": int(OCR_DATA["all_OCR_RMC"][RMC_bar]),
                                                 "Hbar": 0,
                                                 "num": int(OCR_DATA["all_OCR_RMC"][RMC_bar]) - 0}


        # else:
            if self.BOX_result["RboxLen_as400BOX"] != 0:  # 和AS400胶箱比较
                for bar in OCR_DATA["all_OCR_RMC"]:
                    try:
                        if int(OCR_DATA["all_OCR_RMC"][bar]) != int(OCR_DATA["HgetAS400Data"][bar]["BOX"]):
                            self.BOX_result2[bar] = {"RBOX": int(OCR_DATA["all_OCR_RMC"][bar]),
                                                     "ASBOX": int(OCR_DATA["HgetAS400Data"][bar]["BOX"]),
                                                     "num": int(OCR_DATA["all_OCR_RMC"][bar]) - int(
                                                         OCR_DATA["HgetAS400Data"][bar]["BOX"])}
                    except:
                        pass

        for RMC_bar in OCR_DATA['all_OCR_RMC']:
            try:
                if int(OCR_DATA['all_OCR_RMC'][RMC_bar]) != int(H_BOX[RMC_bar]):
                    self.BOX_result2[RMC_bar] = {"Rbar": int(OCR_DATA['all_OCR_RMC'][RMC_bar]),
                                             "Hbar": int(H_BOX[RMC_bar]),
                                             "num": int(OCR_DATA['all_OCR_RMC'][RMC_bar]) - int(H_BOX[RMC_bar])
                                             }
            except KeyError as e:
                self.BOX_result2[RMC_bar] = {"Rbar": int(OCR_DATA['all_OCR_RMC'][RMC_bar]),
                                         "Hbar": 0,
                                         "num": int(OCR_DATA['all_OCR_RMC'][RMC_bar]) - 0
                                         }

    # 读取条码与点胶箱数
    def Rbar_Rbox(self, OCR_DATA):
        self.Loop_sum += 1
        if self.Loop_sum < 3:
            # 扫描条码与实物胶箱数量
            if self.BOX_result["RbarLen_RboxLen"] > 0:
                self.sinOUT.emit("result&条码多于胶箱数, 触发异常")
            elif self.BOX_result["RbarLen_RboxLen"] < 0:
                self.sinOUT.emit("result&条码少于胶箱数, 触发自动扫描")
                bar = input(">>>")
                pass
                if bar:
                    OCR_DATA["minbarList"].append(bar)  # 添加到OCR扫描数据
                    OCR_DATA["RMC_barList"], OCR_DATA["scan_RMC_count"], OCR_DATA["all_OCR_RMC"] = self.get_Scan_RMC_bar(OCR_DATA["minbarList"])
                self.check_BOX(OCR_DATA)
        else:
            self.sinOUT.emit("result&OCR扫描异常, 触发现场处理")
            bar = input(">>>")
            if bar:
                OCR_DATA["minbarList"].append(bar)

    # 读取的条码正确性判断
    def check_RMC(self, OCR_DATA, result_dict, result_dict2):
        # 扫码条码长度与高拍仪识别条码长度
        RMC_barList = OCR_DATA["RMC_barList"]      # ORC扫描RMC条码集合
        min_HRMC_list = OCR_DATA["min_HRMC_list"]  # 高拍仪扫RMC描条码集合
        HAS400RMC = OCR_DATA["HAS400RMC"]          # 来货指RMC条码集合
        # OCR条码与高拍仪条码比较   R_H_alike_bar: 相同部分数据,  R_H_much_bar: 异常部分数据
        R_H_alike_bar, R_H_much_bar = self.get_scan_mare_RMC(RMC_barList, min_HRMC_list)
        # 不为空数据数据有不一样的    0000 ~ 1111  有16种状态
        for much_bar in R_H_much_bar:
            con_item_dict = {"RMC_bar": much_bar}
            if_empty = self.ocr_db_obj.if_empty(con_item_dict, db_name="as400_sync")        # 检查出货指令是否有该部番
            if much_bar in RMC_barList:                 # 在扫描条码里, 在as400条码里, 不在搞拍仪条码里
                if much_bar in HAS400RMC:               # 在高拍仪关联的数据里
                    result_dict2[much_bar] = {"OCR": 1, "HAS": 1, "H": 0, "AS": 1, "code": "1101"}     # 高拍仪读错/漏读 HAS 高拍仪AS400数据
                else:
                    if if_empty:   # 无关联存在AS400
                        AS = 1
                    else:
                        AS = 0
                    result_dict2[much_bar] = {"OCR": 1, "HAS": 0, "H": 0, "AS": AS,  "code": "100" + str(AS)}     # OCR读错

            elif much_bar in min_HRMC_list:   # 在高拍仪 不在OCR
                if much_bar in HAS400RMC:
                    result_dict2[much_bar] = {"OCR": 0, "HAS": 1, "H": 1, "AS": 1, "code": "011"}     # OCR读错/漏读
                else:
                    if if_empty:  # 无关联存在AS400
                        AS = 1
                    else:
                        AS = 0
                    result_dict2[much_bar] = {"OCR": 0, "HAS": 0, "H": 1, "AS": AS, "code": "001" + str(AS)}    # 高拍仪读错

        # 扫描条码和AS400条码比较
        R_AS_alike_bar, R_AS_much_bar = self.get_scan_mare_RMC(RMC_barList, HAS400RMC)

        if R_AS_much_bar:
            for much_bar in R_AS_much_bar:
                con_item_dict = {"RMC_bar": much_bar}
                if_empty = self.ocr_db_obj.if_empty(con_item_dict, db_name="as400_sync")
                if if_empty:  # 无关联存在AS400
                    AS = 1
                else:
                    AS = 0
                if much_bar in RMC_barList:
                    if much_bar in min_HRMC_list:
                        result_dict2[much_bar] = {"OCR": 1, "HAS": 0, "H": 1, "AS": AS, "code": "101" + str(AS)}      # 多来或来错
                    else:
                        result_dict2[much_bar] = {"OCR": 1, "HAS": 0, "H": 0, "AS": AS, "code": "100" + str(AS)}      # OCR读错
                else:
                    if much_bar in min_HRMC_list:
                        result_dict2[much_bar] = {"OCR": 0, "HAS": 1, "H": 1, "AS": AS, "code": "011" + str(AS)}        # OCR漏读码
                    else:
                        result_dict2[much_bar] = {"OCR": 0, "HAS": 1, "H": 0, "AS": AS, "code": "010" + str(AS)}        # 少来货
        return result_dict, result_dict2

    # 高拍仪识别的REQ 判断是否有修改
    def alter_HREQ(self, max_ticketDict):
        for max_bar in max_ticketDict:
            for RMC_bar in max_ticketDict[max_bar]:
                if max_ticketDict[max_bar][RMC_bar]["is_alter"]:   # 0 不修改, 1 为识别为有修改
                    alter_value = max_ticketDict[max_bar][RMC_bar]["alter_item"].split(":")[1]
                    item = max_ticketDict[max_bar][RMC_bar]["alter_item"].split(":")[0]
                    max_ticketDict[max_bar][RMC_bar][item] = int(alter_value)     # 修改数据
        return max_ticketDict   # 返回修好的数据

    # REQ
    def check_REQ(self, OCR_DATA):
        for as_dataDict in OCR_DATA["HgetAS400Data"]:
            ticket_bar = as_dataDict["ticket_bar"]
            RMC_bar = as_dataDict["RMC_bar"]
            try:
                if int(as_dataDict["REQ"]) != int(OCR_DATA["max_ticketDict"][ticket_bar][RMC_bar]["REQ"]):
                    ASREQ = int(as_dataDict["REQ"])  # AS400REQ数量
                    HREQ = int(OCR_DATA["max_ticketDict"][ticket_bar][RMC_bar]["REQ"])   # 高拍仪REQ数量
                    self.REQ_result[RMC_bar] = {"HREQ": HREQ, "ASREQ": ASREQ, "num": HREQ-ASREQ}
            except KeyError as e:
                pass


    # 获取 查询出张出库票的数据
    def update_get_outTicket_db(self, RMC_bar, error_str, H_result):
        # 更新数据表信息
        self.ocr_db_obj.update_db_data(con_item="RMC_bar", con_itemValue=RMC_bar, serial_number=self.serial_number,
                                       item_value=error_str, result=H_result)
        out_ticket_data = self.ocr_db_obj.item_getdata(item_value=RMC_bar, serial_number=self.serial_number, db_name="out_ticket")
        return out_ticket_data       # 返回该条码在数据库的数据

    # OCE, HAS, H, AS,   1111
    def result(self, max_ticketDict, start_time, end_time):
        self.sinOUT.emit("result&%s" % "进入数据结果处理")
        PASS_DATA = {}
        for max_bar in max_ticketDict:
            for RMC_bar in max_ticketDict[max_bar]:
                PASS_DATA[RMC_bar] = max_ticketDict[max_bar][RMC_bar]    # 扫描到的数据添加到到提交数据里
                PASS_DATA[RMC_bar]["ticket_bar"] = max_bar
                PASS_DATA[RMC_bar]["start_time"] = start_time
                PASS_DATA[RMC_bar]["end_time"] = end_time
                PASS_DATA[RMC_bar]["error_code"] = None
                PASS_DATA[RMC_bar]["pend"] = None           # 待处理状态, 1是待处理,  0或空为可上传
                PASS_DATA[RMC_bar]["describe"] = None     # 错误描述

        # 读取条码与点胶箱, 点胶箱与关系AS胶箱, 读条码种类与高拍仪条码种类, 读条码种类与AS400条码种类, 高拍仪读胶箱与关联AS400胶箱, 读条码数量与关联条码数量 , 读条码数量与高拍仪条码数量
        # 'code': '1011011'
        # 0: 相等, 1: 大于, 8: 小于       'OCR': 1, 'HAS': 0, 'H': 0, 'AS': 0, 'code': '1000'
        for RMC_bar in self.RMC_result:
            # 条码错
            if self.RMC_result[RMC_bar]['code'] == '1000':
                if self.BOX_result["code"] == "0111011":
                    error_str = "%s 来错货: " % RMC_bar
                    error_str = "退回处理: " + error_str
                    self.out_GUI(error_str)
                    self.out_GUI(self.RMC_result[RMC_bar])
                else:
                    error_str = "%s 条码扫错: " % RMC_bar
                    self.out_GUI(error_str)
                    self.out_GUI(self.RMC_result[RMC_bar])
                    error_str = "现场确认: " + error_str
                # 同时更新 ocr_scan_log 和 out_ticket表
                self.ocr_db_obj.update_db_data(con_item="RMC_bar", con_itemValue=RMC_bar, serial_number=self.serial_number, item_value=error_str)
                # 数据库数据查询  返回列表套字典
                OCR_scan_log = self.ocr_db_obj.item_getdata(item_value=RMC_bar, serial_number=self.serial_number)
                email_type = 0              # 邮件类型

            # 无包装票  数据接收通知外仓补电子票
            elif self.RMC_result[RMC_bar]['code'] == '0111':
                if self.BOX_result['code'] == '0888088':
                    error_str = "%s 实物少到" % RMC_bar + "  按实际数量汇报"
                    self.out_GUI(error_str)
                    self.out_GUI(self.RMC_result[RMC_bar])
                    error_str = "待外仓处理" + error_str
                else:
                    error_str = "%s OCR漏读或不读码 请现场处理!" % RMC_bar

                    self.out_GUI(error_str)
                    self.out_GUI(self.RMC_result[RMC_bar])
                H_result = 0
                H_scan_log = self.update_get_outTicket_db(RMC_bar, error_str, H_result)  # 更新记录 返回记录信息
                email_type = 1

            # 实物没到
            elif self.RMC_result[RMC_bar]['code'] == '0101':
                error_str = "%s 实物没到: " % RMC_bar
                self.out_GUI(error_str)
                self.out_GUI(self.RMC_result[RMC_bar])
                error_str = "待外仓补货" + error_str
                H_result = 0
                H_scan_log = self.update_get_outTicket_db(RMC_bar, error_str, H_result)     # 更新记录 返回记录信息
                email_type = 1

            # 实物来错, AS400无备案
            elif self.RMC_result[RMC_bar]['code'] == '1010':
                error_str = "%s 漏做柜 AS400无备案: " % RMC_bar
                self.out_GUI(error_str)
                self.out_GUI(self.RMC_result[RMC_bar])
                self.out_GUI('联络外仓库补系统中补做柜号后才可汇报, 已邮件通知!')
                H_result = 0
                H_scan_log = self.update_get_outTicket_db(RMC_bar, error_str, H_result)     # 更新记录 返回记录信息
                email_type = 1

            # 部番来错
            elif self.RMC_result[RMC_bar]['code'] == '1101':
                self.out_GUI("%s 部番来错: " % RMC_bar)
                self.out_GUI(self.RMC_result[RMC_bar])
                error_str = "部番来错"
                H_result = 0
                self.ocr_db_obj.update_db_data(con_item="RMC_bar", con_itemValue=RMC_bar, serial_number=self.serial_number, item_value=error_str, result=H_result)

            # 条码在OCR和AS400出现, 大票无记录
            elif self.RMC_result[RMC_bar]['code'] == '1001':
                error_str = "%s 部番来错, 数据不在出张出库票里在AS400" % RMC_bar
                self.out_GUI(error_str)
                self.out_GUI('异常到收发室登记，收发室邮件联络外仓')
                self.out_GUI(self.BOX_result2[RMC_bar])
                self.OCR_db_obj.update_date(RMC_bar, self.serial_number, error_str)  # 数据更新
                H_result = 0
                H_scan_log = self.update_get_outTicket_db(RMC_bar, error_str, H_result)     # 更新记录 返回记录信息
                email_type = 1


            # 条码在OCR和AS400出现, 大票无记录
            elif self.RMC_result[RMC_bar]['code'] == '1011':
                error_str = "%s 部番来错/来错部番" % RMC_bar
                self.out_GUI(error_str)
                self.OCR_db_obj.update_date(RMC_bar, self.serial_number, error_str)  # 数据更新
                H_result = 0
                H_scan_log = self.update_get_outTicket_db(RMC_bar, error_str, H_result)     # 更新记录 返回记录信息
                email_type = 1

            # 条码只在高拍仪出现
            elif self.RMC_result[RMC_bar]['code'] == '0010':
                self.out_GUI("%s 高拍仪数据识别异常, 系统无此数据" % RMC_bar)
                error_str = "高拍仪数据识别异常, 系统无此数据"
                H_result = 0
                H_scan_log = self.update_get_outTicket_db(RMC_bar, error_str, H_result)     # 更新记录 返回记录信息
                email_type = 1

        # 指示数量 REQ
        for RMC_bar in self.REQ_result:
            is_alter, item, value = self.OutTicket_db_obj.get_Pass_one(RMC_bar)  # 是否修改
            if int(is_alter):   # O 为没有修改, 1 为修改   有修改
                if self.REQ_result[RMC_bar]['num'] > 0:
                    error_str = '出张票上改数量多到:%s, %s=%s, 按实际数量收收发并推送相关担当' % (RMC_bar, item, int(value))
                    self.out_GUI(error_str)
                    self.out_GUI("点货按实际数量汇报")
                    H_result = 1    # 按实际数据收发
                    H_scan_log = self.update_get_outTicket_db(RMC_bar, error_str, H_result)  # 更新记录 返回记录信息
                    email_type = 1
                elif self.REQ_result[RMC_bar]['num'] < 0:
                    error_str = '出张票上改数量少到:%s, %s=%s, 点货按实际数量汇报' % (RMC_bar, item, int(value))
                    self.out_GUI("点货按实际数量汇报, 邮件推送给相关担当!")
                    self.out_GUI(error_str)
                    H_result = 1  # 按实际数据收发
                    self.out_GUI(self.REQ_result[RMC_bar]['num'])
                    H_scan_log = self.update_get_outTicket_db(RMC_bar, error_str, H_result)  # 更新记录 返回记录信息
                    email_type = 1
            else:
                if self.REQ_result[RMC_bar]['num'] > 0:
                    error_str = "%s 部品多到 %s REQ 待外仓补电子票, 然后提交数据!" %(RMC_bar, self.REQ_result[RMC_bar]['num'])   # 点货按实际数量汇报
                    self.out_GUI('异常到收发室登记，收发室邮件联络外仓，外仓数据汇报到工位后货台实物送付, 以邮件通知相关担当!')
                    self.out_GUI(error_str)
                    H_result = 0
                    H_scan_log = self.update_get_outTicket_db(RMC_bar, error_str, H_result)  # 更新记录 返回记录信息
                    email_type = 1

                elif self.REQ_result[RMC_bar]['num'] < 0:
                    error_str = "%s 部品少到 %s REQ, 请及时补货, 数据提交" %(RMC_bar, self.REQ_result[RMC_bar]['num'])         # 点货按实际数量汇报
                    self.out_GUI("异常到收发室登记，收发室邮件联络外仓，货台收货改实数汇报（少到、没到可以改数，多到不能改数）")
                    self.out_GUI(error_str)
                    self.out_GUI(self.REQ_result[RMC_bar])
                    H_result = 0
                    H_scan_log = self.update_get_outTicket_db(RMC_bar, error_str, H_result)  # 更新记录 返回记录信息
                    email_type = 1

                elif self.REQ_result[RMC_bar]['num'] + self.REQ_result[RMC_bar]['ASREQ'] == 0:
                    error_str = "%s 部品未到 %s REQ, 请及时补料" %(RMC_bar, self.REQ_result[RMC_bar]['num'])         # 点货按实际数量汇报
                    self.out_GUI("异常到收发室登记，收发室邮件联络外仓库，货台改数据按0汇报")
                    self.out_GUI(error_str)
                    self.out_GUI(self.REQ_result[RMC_bar])
                    H_result = 0
                    H_scan_log = self.update_get_outTicket_db(RMC_bar, error_str, H_result)  # 更新记录 返回记录信息
                    email_type = 1

        # 胶箱结果
        for RMC_bar in self.BOX_result2:
            try:
                if self.BOX_result2[RMC_bar]['num'] > 0:
                    if self.BOX_result['code'] == '1000011':
                        self.out_GUI("%s 条码贴错货扫描异常" % RMC_bar)
                        self.out_GUI("触发异常")
                    elif self.BOX_result['code'] == '0100011':
                        self.out_GUI("在实物多来异常!!!!")
                        error_str = "%s 实物多来货 %s 箱" % (RMC_bar, self.BOX_result2[RMC_bar]['num'])
                        self.out_GUI(error_str)    #实物少到、多到  按实际数量汇报，少到的数量联络出张组通知供应商补货
                        H_result = 0
                        H_scan_log = self.update_get_outTicket_db(RMC_bar, error_str, H_result)  # 更新记录 返回记录信息
                        email_type = 1

                elif self.BOX_result2[RMC_bar]['num'] < 0:
                    if self.BOX_result["HBOX_AS400BOX"] > 0:
                        self.out_GUI("高拍仪数据多来")
                    elif self.BOX_result["HBOX_AS400BOX"] < 0:
                        self.out_GUI("高拍仪数据少来")
                    else:
                        error_str = "%s 少来货 %s 箱, 请及时补货" % (RMC_bar, self.BOX_result2[RMC_bar]['num'])
                        self.out_GUI(error_str)  # 实物少到、多到  按实际数量汇报，少到的数量联络出张组通知供应商补货
                        H_result = 0
                        H_scan_log = self.update_get_outTicket_db(RMC_bar, error_str, H_result)  # 更新记录 返回记录信息
                        email_type = 1
                else:
                    self.out_GUI("%s 来错货, 扫错码" % (RMC_bar))
            except:
                pass

        # 工厂编号
        for max_bar in self.plant_result:
            if self.plant_result[max_bar]['plant'] == 0:
                error_str = "%s 工厂编号异常" % (max_bar)
                H_result = 0
                # 列表套字典
                H_scan_log = self.ocr_db_obj.item_getdata(item_value=max_bar, serial_number=self.serial_number,
                                                          db_name="out_ticket")
                update_list = []
                # 错误异常记录
                for index, scan_log_dict in enumerate(H_scan_log):
                    update_data = None
                    H_scan_log[index]["error"] = error_str
                    update_data = [error_str, self.serial_number, scan_log_dict["RMC_bar"]]
                    update_list.append(update_data)
                # 更新数据库异常数据
                self.ocr_db_obj.update_db_data(item_value=update_list, result=H_result)
                email_type = 2

    # 结果信号
    def result_print(self):
        self.out_GUI("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
        # 记录
        self.out_GUI("BOX处理结果:%s " % str(self.BOX_result))
        # 异常详细描述
        self.out_GUI("BOX胶箱异常说明:%s " % str(self.BOX_result2))
        # RMC异常
        self.out_GUI("RMC异常集合:%s " % str(self.RMC_result))

        self.out_GUI("程序总用时:%.2f s " % (time.time() - self.start_time))
        self.out_GUI("唯一标识码:%s " % str(self.serial_number))


    # 获取到OCR返回数据,  minbarList: OCR扫描RMC,  max_ticketDict: 高拍仪数据:  start_time: 扫描开始时间, end_time: 扫描结束时间, ocr_read_box_sum: 点胶箱数
    def OCR_AS400(self):
        # 扫描数据处理, 分类, 统计后获取RMC的种类数量  OCR_RMC_count为数据集合
        self.RMC_barList, self.scan_RMC_count, self.all_OCR_RMC = self.get_Scan_RMC_bar(
            self.minbarList)  # [RMC, RMC], RMC=总数量, [RMC: 1, RMC: 2, RMC: 单条码数量]

        # 有修改信息, 修改数据,  读取高拍仪扫描数据, 判断是否有 扫描到修改标记, 有则为有修改记录, 以修改记录真实录入为实际
        self.max_ticketDict = self.alter_HREQ(self.max_ticketDict)


        # 扫描记录插入数据库  OCR数据整理
        for item in self.all_OCR_RMC:
            ocr_scanData = {}
            ocr_scanData["RMC_bar"] = item
            ocr_scanData["BOX"] = int(self.all_OCR_RMC[item])
            ocr_scanData["serial_number"] = int(self.serial_number)
            ocr_scanData["error"] = ""
            self.ocr_log_list.append(ocr_scanData)
        # 列表里添加字典 数据插入
        self.ocr_db_obj.insert_Group_dict(insert_dataDict=self.ocr_log_list, serial_number=self.serial_number,
                                          db_name="ocr_scan_log")

        # 高拍仪数据整理
        for ticket_bar in self.max_ticketDict:
            for RMC_bar in self.max_ticketDict[ticket_bar]:
                outTicket_scanData = {}
                outTicket_scanData["RMC_bar"] = RMC_bar
                outTicket_scanData["ticket_bar"] = ticket_bar
                outTicket_scanData["serial_number"] = self.serial_number
                try:
                    del self.max_ticketDict[ticket_bar][RMC_bar]['scan_time']  # 删除不需要的数据
                except Exception as e:
                    pass
                outTicket_scanData.update(self.max_ticketDict[ticket_bar][RMC_bar])

                self.outTicket_log_list.append(outTicket_scanData)
        # 数据插入搞怕仪
        self.ocr_db_obj.insert_Group_dict(insert_dataDict=self.outTicket_log_list, serial_number=self.serial_number,
                                          db_name='out_ticket')

        # # 高拍仪扫描的所有大票 和RMC条码, 和大票对应工厂代码, 小票对应工厂代码,  数据提取
        self.max_ticket_list, self.min_HRMC_list, self.Hmax_plant_dict, self.Hmin_plant_dict = self.get_RMC_info(
            self.max_ticketDict)
        # # 高拍仪大票 关联 AS400数据, 小票数据  数据关联提取
        self.HgetAS400Data, self.ASmax_plant_dict, self.ASmin_plant_dict, self.HAS400RMC = self.get_as400min_data(
            self.max_ticket_list)

        # 数据集合
        self.OCR_DATA = {
            "minbarList": self.minbarList,  # OCR扫描原始条码数据
            "RMC_barList": self.RMC_barList,  # 去重数据
            "scan_RMC_count": self.scan_RMC_count,  # OCR扫描条码总长度
            "all_OCR_RMC": self.all_OCR_RMC,  # OCR条码集合
            "ocr_read_box_sum": self.ocr_read_box_sum,  # 胶箱数
            "max_ticketDict": self.max_ticketDict,  # 高拍仪数据集合
            "max_ticket_list": self.max_ticket_list,  # 高拍仪大票列表
            "min_HRMC_list": self.min_HRMC_list,  # 高拍仪RMC列表
            "Hmax_plant_dict": self.Hmax_plant_dict,  # 高拍仪大票对应工厂代码,
            "Hmin_plant_dict": self.Hmin_plant_dict,  # 高拍仪小票对应工厂代码,
            "HgetAS400Data": self.HgetAS400Data,  # 高拍仪 大票关联的数据集合  列表套字典
            "ASmax_plant_dict": self.ASmax_plant_dict,  # AS大票对应工厂代码,
            "ASmin_plant_dict": self.ASmin_plant_dict,  # AS小票对应工厂代码,
            "HAS400RMC": self.HAS400RMC,  # 高拍仪 大票关联的小票
            "start_time": self.start_time,  # OCR开始时间
            "end_time": self.end_time  # OCR结束时间
        }

        # 工程代码检查  高拍仪读取工厂与as400工厂号比较2
        # self.check_plant(self.OCR_DATA)

        # 比较点实物胶箱与as400胶箱与读取bar长度对比,    点胶箱, OCR读条码, 出张出库票条码, 出张出库AS400条码
        self.check_BOX(self.OCR_DATA)

        # 扫描到的条码, 和大票对应出来的小条码进行数量, 元素比较
        self.BOX_result, self.RMC_result = self.check_RMC(self.OCR_DATA, self.BOX_result, self.RMC_result)

        # # 高拍仪 AS400REQ
        # self.check_REQ(self.OCR_DATA)
        # 结果整合
        self.result(self.max_ticketDict, self.start_time, self.end_time)

        # 数据发送AS400
        send_AS400_Data = {}
        for get_ticket_bar in self.OCR_DATA["max_ticket_list"]:
            check_db_data = self.ocr_db_obj.item_getdata(item="ticket_bar", item_value=get_ticket_bar, serial_number=self.serial_number, db_name="out_ticket")
            send_AS400_Data[get_ticket_bar] = check_db_data
        # 发送AS400的数据格式   {ticket_bar: [{db_ticket_data}, {db_ticket_data}]}
        # 一个栈板数据集合到一个字典集合, key为每张出张出库票代码, values为列表嵌套字典[{}] 列表里每个字典为该出张出库票上部番号对应的所有数据集合
        print("发送AS400的数据: %s" % send_AS400_Data)
        self.out_GUI("socket: 数提交AS400等待返回结果")

        is_pass = 0
        AS400_return = '667'
        if not AS400_return:
            is_pass = 1
        update_dict = {"is_submit": 1, "submit_count": 1, "AS400_return": AS400_return, 'is_pass': is_pass}
        # sql = update db set is_submit=1, submit_count=1, AS400_return=AS400_return,is_pass=is_pass where ticket_bar=ticket_bar, serial_number=serial_number
        # sql = update out_ticket set is_submit=1, submit_count=1, AS400_return='003',is_pass=0 where ticket_bar=3242136 and serial_number=20210423101019;
        self.ocr_db_obj.update_db_data(db_name='out_ticket', serial_number=self.serial_number, item=update_dict, con_item="ticket_bar", con_itemValue=self.OCR_DATA["max_ticket_list"])
        self.out_GUI("所有出张票的数据:%s " % str(self.OCR_DATA["max_ticket_list"]))

        # 结果输出
        self.result_print()

if __name__=='__main__':
    pass

